package com.example.demo.classload;


import javax.tools.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Test {
    public static HashMap map=new HashMap();
    public static void main(String[] args) throws Exception {
        Test.compiler2();
    }
    public static void compiler2() throws Exception {
        map.put("sxm","自己手写java代码test");
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        DiagnosticCollector diagnostics = new DiagnosticCollector();
        //自己手写java代码
        String code = "import java.util.Map;\n" +
                "\n" +
                "public class HelloWorld {\n" +
                "    public HelloWorld() {\n" +
                "    }\n" +
                "\n" +
                "    public void test(Map map) {\n" +
                "        System.out.println(map.get(\"sxm\"));\n" +
                "    }\n" +
                "\n" +
                "    public void main(String[] var1) {\n" +
                "        System.out.println(\"Hello World\");\n" +
                "    }\n" +
                "}";
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
        MySimpleJavaFileObject simpleJavaFileObject = new MySimpleJavaFileObject("HelloWorld", code);
        Iterable compilationUnits = Arrays.asList(simpleJavaFileObject);
        // options命令行选项
        Iterable<String> options = Arrays.asList("-d",
                "E:\\dscg\\dmp\\DSCG-WebConsoleBackend\\src\\main\\resources");// 指定的路径一定要存在，javac不会自己创建文件夹
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null,
                compilationUnits);

        boolean success = task.call();
        System.out.println((success) ? "编译成功" : "编译失败");
        //类加载
        byte[] clazzByte = loadClass();
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        Method method = Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
        method.setAccessible(true);
        Class clazz = (Class) method.invoke(classLoader, clazzByte, 0, clazzByte.length);
        //类链接
        method = Class.forName("java.lang.ClassLoader")
                .getDeclaredMethod("resolveClass", Class.class);
        method.setAccessible(true);
        method.invoke(classLoader,clazz);
        String[] arr = {"点赞", "关注", "评论", "一键三连"};
        Method testM = clazz.getDeclaredMethod("test", Map.class);
        testM.setAccessible(true);
        Object parameters[]=new Object[] {arr};
        testM.invoke(clazz.newInstance(),map);
    }
    public static byte[] loadClass() throws Exception {
        String path = "E:\\dscg\\dmp\\DSCG-WebConsoleBackend\\src\\main\\resources\\HelloWorld.class";
        FileInputStream in = new FileInputStream(path);
        long fileSize = new File(path).length();
        byte[] clazzSize = new byte[(int) fileSize];
        in.read(clazzSize);
        return clazzSize;
    }

}
class MySimpleJavaFileObject extends SimpleJavaFileObject {

    private String contents = null;
    private String className;

    public MySimpleJavaFileObject(String className, String contents) {
        super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
        this.className = className;
        this.contents = contents;
    }

    public CharSequence getCharContent(boolean ignoredEncodingErrors) throws IOException {
        return contents;
    }

    public String getClassName() {
        return className;
    }
}